package com.jilujia.web.controller;

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jilujia.domain.hotel.Hotel;
import com.jilujia.domain.hotel.service.HotelSearchCriteria;
import com.jilujia.domain.hotel.service.HotelService;
import com.jilujia.domain.user.UserFollowHotel;
import com.jilujia.domain.user.service.UserService;
import com.jilujia.framework.exception.ResourceNotFoundException;
import com.jilujia.framework.security.JilujiaUser;

@Controller
public class HotelsController extends AbstractWebController {

	private static final Logger LOG = LoggerFactory.getLogger(HotelsController.class);

	@Autowired
	private HotelService hotelService;

	@Autowired
	private UserService userService;

	// @Autowired
	// private WebApplicationContext webApplicationContext;

	public HotelsController() {
	}

	@RequestMapping(value = "/hotels/register", method = RequestMethod.GET)
	public String registerHotel(Model model) {
		model.addAttribute(hotelService.createHotel());
		return "hotels/register";
	}

	@RequestMapping(value = "/hotels/register", method = RequestMethod.POST)
	public String persistHotel(@Valid Hotel hotel, BindingResult result, HttpServletRequest request) {
		if (result.hasErrors()) {
			return "hotels/register";
		}

		Hotel newHotel = new Hotel();
		newHotel.setAddress(hotel.getAddress());

		hotel = hotelService.saveHotel(newHotel);

		return "redirect:../hotels/" + hotel.getId();
	}

	@RequestMapping(value = "/hotels/search", method = RequestMethod.GET)
	public void search(HotelSearchCriteria searchCriteria, Principal currentUser, Model model) {
		LOG.debug("search");
	}

	@RequestMapping(value = "/hotels", method = RequestMethod.GET)
	public String list(HotelSearchCriteria criteria, Principal currentUser, Model model) {
		// List<Hotel> hotels = hotelService.findHotels(criteria);
		Page<Hotel> hotels = hotelService.findHotelsByCriteria(criteria);
		model.addAttribute(hotels.getContent());
		return "hotels/list";
	}

	@RequestMapping(value = "/hotels/{id}", method = RequestMethod.GET)
	public String show(@PathVariable Long id, Principal currentUser, Model model) {
		// String cacheKey = "showhotel_" + id;
		// model.addAttribute("cached", true);
		// model.addAttribute("cachekey", cacheKey);
		//
		// if (cacheManager.getCache("PageCache").get(cacheKey) != null) {
		// return "hotels/show";
		// }
		Hotel hotel = hotelService.findHotelById(id);

		if (hotel == null) {
			throw new ResourceNotFoundException(id);
		}

		if (currentUser != null) {
			JilujiaUser currentRealUser = this.findUserByCurrentUser(currentUser);

			UserFollowHotel userFollowHotel = userService.findByUserIdAndHotelId(currentRealUser.getUserId(), id);

			if (userFollowHotel != null) {
				model.addAttribute(userFollowHotel);
			}
		}

		model.addAttribute(hotel);
		model.addAttribute("viewCount", hotelService.getViewCount(id));

		return "hotels/show";
	}

	@RequestMapping(value = "/hotels/follow/{hotelId}", method = RequestMethod.POST)
	@Secured( { "ROLE_USER" })
	public @ResponseBody
	String followHotel(@PathVariable Long hotelId, Principal currentUser) {
		LOG.debug("userFollow:" + hotelId);
		JilujiaUser currentRealUser = findUserByCurrentUser(currentUser);
		hotelService.followHotel(currentRealUser.getUserId(), hotelId);

		return "success";
	}

	@RequestMapping(value = "/hotels/unfollow/{hotelId}", method = RequestMethod.POST)
	@Secured( { "ROLE_USER" })
	public @ResponseBody
	String unfollowHotel(@PathVariable Long hotelId, Principal currentUser) {
		LOG.debug("userFollow:" + hotelId);
		JilujiaUser currentRealUser = findUserByCurrentUser(currentUser);
		hotelService.unfollowHotel(currentRealUser.getUserId(), hotelId);

		return "success";
	}
}
